﻿using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace My.Core.Swagger.Filters
{
	/// <summary>
	/// 全局接口认证过滤器
	/// </summary>
	public class AuthenticationOperationFilter : IOperationFilter
    {
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var actionScopes = context.MethodInfo.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Select(attr => attr.TypeId.ToString()).Distinct();
            var controllerScopes = context.MethodInfo.DeclaringType!.GetCustomAttributes(true)
                .Union(context.MethodInfo.GetCustomAttributes(true))
                .OfType<AuthorizeAttribute>()
                .Select(attr => attr.TypeId.ToString());
            var requiredScopes = actionScopes.Union(controllerScopes).Distinct().ToArray();
            if (requiredScopes.Any())
            {
				// 声明一个oAuthScheme，注意下面的Id要和AddSecurityDefinition中的参数name一致
				var oAuthScheme = new OpenApiSecurityScheme
                {
                    Scheme = JwtBearerDefaults.AuthenticationScheme, //"Bearer"
                    Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" }
                };

				// 注册全局认证（所有的接口都可以使用认证）
				operation.Security = new List<OpenApiSecurityRequirement>
                {
                    new OpenApiSecurityRequirement
                    {
                        [ oAuthScheme ] = new List<string>()
                    }
                };
            }
        }
    }
}
